package org.jeecg.modules.business.strategy.impl;

import cn.hutool.core.util.ObjectUtil;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.util.DateUtils;
import org.jeecg.modules.business.entity.*;
import org.jeecg.modules.business.service.IBusOrderFeeService;
import org.jeecg.modules.business.service.impl.BusBookingRoomsServiceImpl;
import org.jeecg.modules.business.strategy.PricingStrategy;
import org.jeecg.modules.business.strategy.util.PricingUtil;
import org.jeecg.modules.rooms.entity.CesAllDayPriceRule;
import org.jeecg.modules.rooms.entity.CesHourRoomRule;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

@Slf4j
@Component("minuteAddStrategy")
public class MinuteAddStrategy  implements PricingStrategy {

    @Autowired
    IBusOrderFeeService feeService;

    @Autowired
    private BusBookingRoomsServiceImpl bookingRoomsService;

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Autowired
    PricingUtil pricingUtil;

    @Override
    public void calculateFee(BusRoomsLivingOrder livingOrder, CesAllDayPriceRule cesAllDayPriceRule, List<CesHourRoomRule> hourRoomRuleList) {
        Date date = new Date();
        Calendar nextCalendar = Calendar.getInstance();
        Calendar nowCalendar = Calendar.getInstance();
        nextCalendar.setTime(date);
        BusBookingRooms bookingroom = bookingRoomsService.getById(livingOrder.getBookingRoomId());
        if (ObjectUtil.isEmpty(bookingroom)){
            log.info("未找到订单{}对应的房间", livingOrder.getId());
            return;
        }
        // 查询当天房间超时消费
        BusOrderFee fee = pricingUtil.getOverTimeFee(livingOrder, bookingroom);
        // 需要支付完整费用时间的最后时间
        Date endTime = pricingUtil.getFullFeeTime(date, cesAllDayPriceRule);
        // 当前时间加上超时收费时间
//        nextCalendar.add(Calendar.MINUTE, cesAllDayPriceRule.getMinute());
        // 获取今日第一次超时时间
        nextCalendar = pricingUtil.getRemindTime(livingOrder, cesAllDayPriceRule, 1);
        nextCalendar.set(Calendar.YEAR, nowCalendar.get(Calendar.YEAR));
        nextCalendar.set(Calendar.MONTH, nowCalendar.get(Calendar.MONTH));
        nextCalendar.set(Calendar.DATE, nowCalendar.get(Calendar.DATE));
        // 今日超时分钟
        Integer overMinutes = Math.round((nowCalendar.getTimeInMillis() - nextCalendar.getTimeInMillis()) / (1000 * 60 ));
        if (overMinutes < 0){
            return;
        }
        //已经超时的 不足时间
        Integer minutesDiff = overMinutes % cesAllDayPriceRule.getMinute();
        // 超出 超时时间 的数量
        int minutesDiffNum = (int) Math.floor(overMinutes / cesAllDayPriceRule.getMinute());

        int moreThenMinuteDiffNum = (int) Math.floor(minutesDiff / cesAllDayPriceRule.getMoreThenMinute());
        // 加上下一次不足时间 >= 超出时间，用超出时间
        if (minutesDiff + cesAllDayPriceRule.getMoreThenMinute() > cesAllDayPriceRule.getMinute()){
            int newOverTime = cesAllDayPriceRule.getMinute() * (minutesDiffNum + 1);
            nextCalendar.add(Calendar.MINUTE, newOverTime);
        }else {
            nextCalendar.add(Calendar.MINUTE, cesAllDayPriceRule.getMoreThenMinute());
        }
//        log.info(DateUtil.format(nextCalendar.getTime(), "yyyy-MM-dd HH:mm"));

        log.info("{}今日超时分钟{}，超时时间数量{}，不足时间数量{}",livingOrder.getId(),overMinutes,minutesDiffNum,moreThenMinuteDiffNum);

        // 当前时间加上超时收费时间 < 按全天收费时间的标准
        if (nextCalendar.getTime().compareTo(endTime) < 0){
            // 不满足的情况下，添加超时收费，设置下一次收费时间戳
            BigDecimal money = cesAllDayPriceRule.getPrice().multiply(BigDecimal.valueOf(minutesDiffNum))
                    .add(cesAllDayPriceRule.getMoreThenPrice().multiply(BigDecimal.valueOf(moreThenMinuteDiffNum)));
            fee.setDayTime(date);
            fee.setMoney(money);
            redisTemplate.opsForZSet().remove("overTimerOrder",livingOrder.getId());

            // 如果下一次增加收费时间大于 全天收费时间 设置
        }else {
            // 如果满足全天收费要求，预离时间增加1天
            BusLivingLayoutDayPrice dayPrice = pricingUtil.addDayPrice(livingOrder, bookingroom, bookingroom.getRoomLayoutId());
            fee.setMoney(dayPrice.getPrice());
            fee.setDayTime(date);
            // 获取每天超时时间，如果超过预离时间，修改预离时间
            nextCalendar = pricingUtil.getNextCalendar(livingOrder, nowCalendar,cesAllDayPriceRule);
            fee.setRemark(DateUtils.formatDate(nowCalendar.getTime(), "MM-dd") + "房费");
            fee.setIsOverTime(false);
        }
        // 移除处理过的时间订单，添加订单下一次超时的时间戳
        redisTemplate.opsForZSet().remove("overTimerOrder",livingOrder.getId());
        redisTemplate.opsForZSet().add("overTimerOrder",livingOrder.getId(),nextCalendar.getTimeInMillis());
        // 添加超时房费
        feeService.saveOrUpdate(fee);
    }

}

